package com.miracle.moa.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miracle.common.Result;
import com.miracle.common.StatusCode;
import com.miracle.moa.manager.entity.Role;
import com.miracle.moa.manager.entity.RolePermission;
import com.miracle.moa.manager.entity.UserRole;
import com.miracle.moa.manager.mapper.RoleMapper;
import com.miracle.moa.manager.service.IRolePermissionService;
import com.miracle.moa.manager.service.IRoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.miracle.moa.manager.service.IUserRoleService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author miracle
 * @since 2021-03-22
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IUserRoleService userRoleService;

    @Override
    public List<Role> findAllRoleByUserId(Integer userId) {
        return roleMapper.findAllRoleByUserId(userId);
    }

    @Override
    public IPage<Role> rolePage(int page, int pageSize, String keyword) {
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(keyword)) {
            queryWrapper.lambda().like(Role::getRoleName, keyword).or().like(Role::getRoleCode, keyword);
        }
        IPage<Role> rolePage = super.page(new Page<>(page, pageSize), queryWrapper);
        List<Role> records = rolePage.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            for (Role record : records) {
                QueryWrapper<RolePermission> wr = new QueryWrapper<>();
                List<RolePermission> list = rolePermissionService.list(wr.lambda().eq(RolePermission::getRoleId, record.getId()));
                List<Integer> permissions = list.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
                record.setPermissions(permissions);
            }
        }
        return rolePage;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Role> saveRole(Role role) {

        LocalDateTime now = LocalDateTime.now();
        role.setCreateTime(now);
        role.setUpdateTime(now);

        super.save(role);
        this.saveRolePermissionBatch(role);
        return new Result<>(StatusCode.OK, "保存成功", role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Role> updateRole(Role role) {
        LocalDateTime now = LocalDateTime.now();
        role.setUpdateTime(now);

        super.updateById(role);

        /* 删除重建角色所属权限 */
        this.removeRolePermissionByRoleId(role.getId());
        this.saveRolePermissionBatch(role);

        return new Result<>(StatusCode.OK, "保存成功", role);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result deleteRole(Integer id) {
        super.removeById(id);
        this.removeRolePermissionByRoleId(id);

        /* 还需要删除用户关联信息 */
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserRole::getRoleId, id);
        userRoleService.remove(queryWrapper);

        return new Result(StatusCode.OK, "删除成功");
    }

    /**
     * 批量保存角色权限关联信息
     * @param role 角色
     */
    private void saveRolePermissionBatch(Role role) {
        List<Integer> permissions = role.getPermissions();
        if (!CollectionUtils.isEmpty(permissions)) {
            List<RolePermission> rolePermissions = new ArrayList<>();
            for (Integer permissionId : permissions) {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setPermissionId(permissionId);
                rolePermission.setRoleId(role.getId());
                rolePermissions.add(rolePermission);
            }
            rolePermissionService.saveBatch(rolePermissions);
        }
    }

    /**
     * 根据角色id删除角色权限关联信息
     * @param roleId 角色编码
     */
    private void removeRolePermissionByRoleId(Integer roleId) {
        /* 删除角色所属权限 */
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(queryWrapper);
    }
}
